#pragma once
#include<iostream>
#include"Tasks.hpp"
#include<unistd.h>
#include<vector>
#include<string>
const int gdefaultnum=4;

class Channel
{
    public:
    Channel(int arr,pid_t id)
    :_wfd(arr)
    ,_subid(id)
    {
        _name="channel-"+std::to_string(_wfd)+"-"+std::to_string(_subid);
    }
    void Send(int n)
    {
        int ret=write(_wfd,&n,sizeof(n));
        if(ret>=0)
        {
            std::cout<<"发送了一个任务码"<<std::endl;
        }
        else
        {
            std::cout<<"发送失败"<<ret<<std::endl;
        }
    }
    std::string& Name()
    {
        return _name;
    }
    private:
    int _wfd;
    pid_t _subid;
    std::string _name;
};
class ChannelManager
{
    public:
    ChannelManager()
    :_next(0)
    {}
    void Insert(int arr,pid_t id)
    {
        Channel _cm(arr,id);
        _channels.push_back(_cm);
    }
    Channel& Select()
    {
        //考虑负载均衡采用轮巡方式：
        Channel& c=_channels[_next];
        _next++;
        if(_next>_channels.size())
        {
            _next%=_channels.size();
        }
        return c;
    }
    private:
    std::vector<Channel> _channels;
    int _next;
};


class ProcessPool
{
    public:
    ProcessPool(int n)
    :process_num(n)
    {
        _tasks.Register(PrintLog);
        _tasks.Register(Downloaad);
        _tasks.Register(UpLoad);
    }
    //子进程执行方向
    void Work()
    {
        while(1)
        {
            int buffer[1024];
            int ret=read(3,buffer,sizeof(int));
            if(ret>0)
            {
                if(ret==sizeof(int))
                {
                    //表示读正确了:
                    std::cout<<"子进程收到了一个任务码 "<<ret<<std::endl;
                    //随机选一个任务下标：
                    int code=_tasks.Code();
                    //执行任务：
                    _tasks.Execute(code);
                }
                else
                {
                    //表示读错了继续读:
                    continue;
                }
            }
            else if(ret==0)
            {
                //读到文件末尾表示父进程关闭了管道：
                std::cout<<"父进程退出子进程也退出"<<std::endl;
                break;
            }
            else
            {
                std::cout<<"read fail"<<std::endl;
                break;
            }
        }
    }
    //创建基于匿名管道的进程池：
    void Creat()
    {
        for(int i=0;i<process_num;i++)
        {
            int arr[2]={0};
            int ret=pipe(arr);
            if(ret<0)
            {
                std::cout<<"pipe fail"<<std::endl;
                break;
            }
            std::cout<<"pipe success"<<std::endl;
            pid_t id=fork();
            if(id==0)
            {
                //child
                //关闭不需要的文件描述符：
                close(1);
                Work();
                exit(0);
            }
            else if(id>0)
            {
                //parent
                close(0);
                _cm.Insert(arr[0],id);
            }
            else
            {
                std::cout<<"fork fail"<<std::endl;
                break;
            }
            
        }
    }
    void Run()
    {
        //首先选择一个信道：
        std::cout<<"run"<<std::endl;
        Channel& ret=_cm.Select();
        std::cout<<"选择了一个子进程："<<ret.Name()<<std::endl;
        //选择一个任务;
        int taskcode=_tasks.Code();
        //发送taskcode
        std::cout<<taskcode<<std::endl;
        ret.Send(taskcode);
    }
    private:
    //processpool中的子进程数量：
    int process_num;
    //进程管理：
    ChannelManager _cm;
    //任务管理：
    TaskManager _tasks;
};